﻿namespace Attacher.VisualStudio
{
    using System;
    using System.Collections.Generic;
    using System.Runtime.InteropServices.ComTypes;

    using EnvDTE;

    internal class VisualStudioInstanceService : IVisualStudioInstanceService
    {
        public IEnumerable<VisualStudioInstance> GetInstances()
        {
            IRunningObjectTable runningObjectTable;
            int getRunningObjectTableResult = NativeMethods.GetRunningObjectTable(0, out runningObjectTable);

            if (getRunningObjectTableResult == NativeMethods.SOk)
            {
                IEnumMoniker enumMoniker;
                runningObjectTable.EnumRunning(out enumMoniker);

                IntPtr fetched = IntPtr.Zero;
                IMoniker[] moniker = new IMoniker[1];
                while (enumMoniker.Next(1, moniker, fetched) == 0)
                {
                    IBindCtx bindCtx;
                    NativeMethods.CreateBindCtx(0, out bindCtx);
                    string displayName;
                    moniker[0].GetDisplayName(bindCtx, null, out displayName);
                    bool isVisualStudio = displayName.StartsWith("!VisualStudio");

                    if (isVisualStudio)
                    {
                        object dte;
                        int getObjectResult = runningObjectTable.GetObject(moniker[0], out dte);
                        if (getObjectResult == NativeMethods.SOk)
                        {
                            DTE visualStudio = (DTE)dte;

                            string title;
                            try
                            {
                                if (string.IsNullOrEmpty(visualStudio.Solution.FullName))
                                {
                                    title = "No solution open";
                                }
                                else
                                {
                                    title = visualStudio.Solution.FullName;
                                }
                                
                            }
                            catch (Exception)
                            {
                                title = "Cannot be retrieved";
                            }

                            yield return new VisualStudioInstance(title, visualStudio);                            
                        }
                    }
                }
            }
        }
    }
}